home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d20 / makearc3.arc / MAKEARC2.C < prev   
Text File  |  1990-12-04  |  22KB  |  877 lines

  1.  
  2. /* MakeArc copyright (c) 1990 by M. Kimes -- All Rights Reserved    */
  3. /* Version 204   You can use this freely.  Check with me before     */
  4. /* releasing modified executables or source, please (I'll probably  */
  5. /* allow it).  Exceptions:  Strict translation to foreign languages */
  6. /* and ports to other platforms (non-IBMPC-compatible).                */
  7. /* Corrections, bug reports, etc. welcome.  Flames ignored by a     */
  8. /* master.                                                          */
  9.  
  10.  
  11. /* Include files; a couple of TC specific here... */
  12.  
  13. #include <conio.h>
  14. #include <dir.h>
  15. #include <time.h>
  16. #include <dos.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <io.h>
  20. #include <fcntl.h>
  21. #include <ctype.h>
  22. #include <process.h>
  23. #include <string.h>
  24.  
  25. /* Couple of typedefs */
  26.  
  27. typedef unsigned int word;
  28. typedef unsigned     bit;
  29.  
  30. /* Message header */
  31.  
  32. struct _msg {
  33.   char from[36];
  34.   char to[36];
  35.   char subj[72];
  36.   char date[20];
  37.   word times;
  38.   word dest;
  39.   word orig;
  40.   word cost;
  41.   word orig_net;
  42.   word dest_net;
  43.   int  msg_filler[4];
  44.   word reply;
  45.   word attr;
  46.   word up;
  47. };
  48.  
  49. /* Message attributes */
  50.  
  51. #define MSGPRIVATE 0x0001
  52. #define MSGCRASH   0x0002
  53. #define MSGREAD    0x0004
  54. #define MSGSENT    0x0008
  55. #define MSGFILE    0x0010
  56. #define MSGFWD     0x0020
  57. #define MSGORPHAN  0x0040
  58. #define MSGKILL    0x0080
  59. #define MSGLOCAL   0x0100
  60. #define MSGXX1     0x0200
  61. #define MSGXX2     0x0400
  62. #define MSGFRQ     0x0800
  63. #define MSGRRQ     0x1000
  64. #define MSGCPT     0x2000
  65. #define MSGARQ     0x4000
  66. #define MSGURQ     0x8000
  67.  
  68. /* Packet header */
  69.  
  70. struct _pkthdr {               /* Mostly copied from JoHo.  I like JoHo. */
  71.     word
  72.         orig_node,             /* originating node */
  73.         dest_node,             /* destination node */
  74.         year,                  /* 1989 - nnnnn */
  75.         month,                   /* 1-12 (note all this wasted space!) */
  76.         day,                   /* 1-31 */
  77.         hour,                   /* 0-23 */
  78.         minute,                   /* 0-59 */
  79.         second,                   /* 0-60 */
  80.         rate,                  /* unused */
  81.         ver,                   /* always 2 */
  82.         orig_net,              /* originating net */
  83.         dest_net;              /* destination net */
  84.     char
  85.         product,               /* product code */
  86.         rev_lev,               /* revision level */
  87.         password[8];
  88.     word
  89.         qm_orig_zone,          /* BARF! */
  90.         qm_dest_zone;           /* BARF! */
  91.     char TRASH[8];               /* Domain? */
  92.     word
  93.         orig_zone,             /* originating zone */
  94.         dest_zone,             /* destination zone */
  95.         orig_point,            /* originating point */
  96.         dest_point;            /* destination point */
  97.     long pr_data;
  98. };
  99.  
  100. /* Global flags and variables */
  101.  
  102. extern char msgattach;                /* Make *.MSG attaches? */
  103. extern word myzone;                    /* For our address */
  104. extern word mynet;                    /* " */
  105. extern word mynode;                    /* " */
  106. extern word mypoint;                /* " */
  107. extern char configfile[133];        /* Config file to read */
  108. extern char root[128];                /* 'Root' outbound dir */
  109. extern char outbound[133];            /* Extended outbound dir */
  110. extern char netdir[128];            /* Net msg directory if *.MSG attaches */
  111. extern char arccmd[128];            /* Default archive command */
  112. extern char alltype;                /* Default mail type */
  113. extern char didbreak;                /* CTRL-BREAK flag */
  114. extern char schedtag[128];            /* Schedule tag */
  115. extern word lines;                    /* For debug info */
  116. extern char debug;                    /* debug on? */
  117. extern char more;                    /* more on? */
  118. extern char usingbink;                /* Use BINKLEY.CFG? */
  119. extern word rzone;                    /* For routing */
  120. extern word rnet;                    /* " */
  121. extern word rnode;                    /* " */
  122. extern word rpoint;                    /* " */
  123.  
  124. /* Function definitions */
  125.  
  126. char     pascal spawnit (char *a);
  127. char     pascal check_4flo (word zone,word net,word node,word point);
  128. char *   pascal stristr (char *t, char *s);
  129. void     cdecl  deinit(void);
  130. void     pascal say_error (long lastpos,FILE *fp);
  131. int      pascal makearc (char *arcfile,char *pktfile,char *origpkt,char *outbound);
  132. word     pascal makeflo(word zone,word net,word node,word point,char *sendfile,char type);
  133. word     pascal makemessage (word zone,word net,word node,word point,char *sendfile,char type);
  134. void     pascal next_name(char *);
  135. void     pascal make_poll (char *line,long lastpos,FILE *fp);
  136. FILE *   pascal analyze(char *);
  137. char *   pascal arcname(word,word);
  138. char *   pascal filename(word,word);
  139. char *   pascal fidodate(void);
  140. char *   pascal lstrip(char *);
  141. char *   pascal rstrip(char *);
  142. char *   pascal stripcr(char *);
  143. int      cdecl  break_handler(void);
  144. void     pascal moveit (struct ffblk *f, char *myoutbound, char *outbound, char type, char archive,word net,word node,word fromzone);
  145. void     pascal move_prep(char *line,long lastpos,FILE *fp);
  146. void     pascal change_mail(char *line,long lastpos,FILE *fp);
  147. long     pascal make_msgid(void);
  148. char *   pascal find_sched(FILE *fp,char *schedtag,int wholefile);
  149. char *   pascal skip_white(char *);
  150. char *   pascal skip_nonwhite(char *);
  151. char *   pascal to_delim(char *,char *);
  152. int      cdecl hardware_error (int errnum,int ax,int bp,int si);
  153.  
  154. /* ID stuff */
  155.  
  156. #define MAKEVER "204"
  157.  
  158. #define PID_ID "MA 204"
  159.  
  160. #define BETA
  161.  
  162.  
  163.  
  164. void pascal move_prep (char *line,long lastpos,FILE *fp) {
  165.  
  166.     char flo[133];                /* Used to find (& destroy) flo files */
  167.     char arc[133];                /* Used to find arc files */
  168.     char pkt[133];                /* Used to find packets */
  169.     unsigned int zone,net,node; /* Address to move to */
  170.     unsigned int fromzone;        /* Zone to move mail from */
  171.     char outbound[84];            /* His calculated outbound name */
  172.     struct ffblk f;                /* The better to find them with, my dearie */
  173.     char *p;                    /* Used to parse address */
  174.     char type;                    /* Type of mail ([H]old, [C]rash, etc.) */
  175.  
  176.     lstrip(line);
  177.     stripcr(line);
  178.     rstrip(line);
  179.     p=strtok(line," ");
  180.     if(!p) return;
  181.     fromzone=(word)atol(p);
  182.     if(!fromzone) return;
  183.     p=strtok(0,":");
  184.     if(!p) return;
  185.     zone=(word)atol(p);
  186.     if(zone==fromzone) return;    /* Duh... */
  187.     if(!zone) return;
  188.     p=strtok(0,"/");
  189.     if(!p) return;
  190.     net=(word)atol(p);
  191.     if(!net) return;
  192.     p=strtok(0," ");
  193.     if(!p) return;
  194.     node=(word)atol(p);
  195.     p=strtok(0,";\n");
  196.     type=toupper(*p);
  197.     if(type!='H' && type!='C' && type!='F' && type!='D' && type!='N' && type!='O') return;
  198.  
  199.     /* Make mask for outbound flo, packet and arc files */
  200.  
  201.     if(fromzone!=myzone) {
  202.         sprintf(pkt,"%s.%03x\\%04x%04x.?UT",root,fromzone,net,node);
  203.         sprintf(arc,"%s.%03x\\%04x%04x.*",root,fromzone,mynet-net,mynode-node);
  204.         sprintf(flo,"%s.%03x\\%04x%04x.?LO",root,fromzone,net,node);
  205.     }
  206.     else {
  207.         sprintf(pkt,"%s\\%04x%04x.?UT",root,net,node);
  208.         sprintf(arc,"%s\\%04x%04x.*",root,mynet-net,mynode-node);
  209.         sprintf(flo,"%s\\%04x%04x.?LO",root,net,node);
  210.     }
  211.     if(zone!=myzone) sprintf(outbound,"%s.%03x",root,zone);
  212.     else strcpy(outbound,root);
  213.  
  214.     if(!findfirst(flo,&f,0)) {
  215.         printf("Removing FLO files addressed to %u:%u/%u\n",fromzone,net,node);
  216.         do {
  217.             if(fromzone==myzone) sprintf(flo,"%s\\%s",root,f.ff_name);
  218.             else sprintf(flo,"%s.%03x\\%s",root,fromzone,f.ff_name);
  219.             unlink(flo);
  220.         } while(!findnext(&f));
  221.     }
  222.     if(!findfirst(pkt,&f,0)) {
  223.         if(fromzone==myzone) {
  224.             moveit(&f,root,outbound,type,0,net,node,fromzone);
  225.         }
  226.         else {
  227.             sprintf(flo,"%s.%03x",root,fromzone);
  228.             moveit(&f,flo,outbound,type,0,net,node,fromzone);
  229.         }
  230.     }
  231.     if(!findfirst(arc,&f,0)) {
  232.         if(fromzone==myzone)moveit(&f,root,outbound,type,1,net,node,fromzone);
  233.         else {
  234.             sprintf(flo,"%s.%03x",root,fromzone);
  235.             moveit(&f,flo,outbound,type,0,net,node,fromzone);
  236.         }
  237.     }
  238.     return;
  239. }
  240.  
  241.  
  242.  
  243.  
  244. void pascal moveit (struct ffblk *f, char *myoutbound, char *outbound, char type, char archive,word net,word node,word fromzone) {
  245.  
  246.     union REGS r;
  247.     struct SREGS sregs;
  248.     FILE *fp=NULL;
  249.     FILE *fp2;
  250.     char once=0;
  251.  
  252.     char wasname[133];
  253.     char isname[133];
  254.  
  255.     if(archive) {                   /* If archive, open flo file for append */
  256.         sprintf(wasname,"%s\\%04x%04x.%cLO",outbound,net,node,type);
  257.         fp=fopen(wasname,"at");
  258.         if(fp)fseek(fp,0L,SEEK_END);
  259.     }
  260.  
  261.     do {
  262.         if(f->ff_fsize==0L) continue;
  263.         if(!once){
  264.             if(archive)printf("Moving archived mail addressed to %u:%u/%u\n",fromzone,net,node);
  265.             else printf("Moving packets addressed to %u:%u/%u\n",fromzone,net,node);
  266.         }
  267.         once=1;
  268.         sprintf(wasname,"%s\\%s",myoutbound,f->ff_name);
  269.         sprintf(isname,"%s\\%s",outbound,f->ff_name);
  270.         if(!archive)isname[strlen(isname)-3]=type;           /* Set mail type */
  271.         r.h.ah=0x56;
  272.         r.x.dx=FP_OFF(wasname);
  273.         sregs.ds=FP_SEG(wasname);
  274.         r.x.di=FP_OFF(isname);
  275.         sregs.es=FP_SEG(isname);
  276.         int86x(0x21,&r,&r,&sregs);               /* Move 'em */
  277.         if(archive) {                           /* Only for archives */
  278.             fp2=fopen(wasname,"wb");
  279.             if(fp2)fclose(fp2);                   /* Leave truncated filename */
  280.             if(fp) fprintf(fp,"^%s\n",isname); /* Add name to the flo file */
  281.         }
  282.     } while(!findnext(f));                       /* Til there ain't no more */
  283.  
  284.     if(fp) {
  285.         fseek(fp,0L,SEEK_END);
  286.         if(ftell(fp)==0L) {
  287.             fclose(fp);
  288.             sprintf(wasname,"%s\\%04x%04x.%cLO",outbound,net,node,type);
  289.             unlink(wasname);
  290.         }
  291.         else fclose(fp);
  292.     }
  293. }
  294.  
  295.  
  296. void pascal change_mail (char *line,long lastpos,FILE *fp) {
  297.  
  298.     unsigned int zone,net,node; /* Address to change mail type for */
  299.     char flo[133];
  300. /*    char req[133];    */
  301.     char pkt[133];
  302.     char outbound[84];
  303.     struct ffblk f;
  304.     struct ffblk f1;
  305.     char *p;
  306.     char type;
  307.     char s[133];
  308.     char s1[133];
  309.     FILE *infile=NULL;
  310.     FILE *outfile;
  311.     unsigned int bytes;
  312.  
  313.     lstrip(line);
  314.     stripcr(line);
  315.     rstrip(line);
  316.     zone=myzone;
  317.     net=0;
  318.     node=0;
  319. printf("!!!%s!!!\n",line);
  320.     if(!strnicmp(line,"ALL ",4)) {    /* This doesn't work yet; don't use it */
  321.         p=line+4;
  322.         lstrip(p);
  323. printf("!!!%s!!!\n",p);
  324.         if(!strnicmp(p,"ZONE ",5)) {
  325.             p+=5;
  326.             lstrip(p);
  327. printf("!!!%s!!!\n",p);
  328.             zone=(word)atol(p);
  329.             if(!zone) {
  330.                 fprintf(stderr,"\nZero Zone #\n");
  331.                 say_error(lastpos,fp);
  332.                 return;
  333.             }
  334.         }
  335.         if(strchr(p,' ')) {
  336.             p=strchr(p,' ');
  337.             p++;
  338.             type=*p;
  339.         }
  340.         else type=alltype;
  341.         p=NULL;
  342.     }
  343.     else {
  344.         p=strtok(line,":");
  345.         if(!p) {
  346.             fprintf(stderr,"\nMissing Zone\n");
  347.             say_error(lastpos,fp);
  348.             return;
  349.         }
  350.         zone=(word)atol(p);
  351.         if(!zone) {
  352.             fprintf(stderr,"\nZero Zone\n");
  353.             say_error(lastpos,fp);
  354.             return;
  355.         }
  356.         p=strtok(0,"/");
  357.         if(!p) {
  358.             fprintf(stderr,"\nMissing Net\n");
  359.             say_error(lastpos,fp);
  360.             return;
  361.         }
  362.         net=(word)atol(p);
  363.         if(!net) {
  364.             fprintf(stderr,"\nZero Net\n");
  365.             say_error(lastpos,fp);
  366.             return;
  367.         }
  368.         p=strtok(0," ");
  369.         if(!p) {
  370.             fprintf(stderr,"\nMissing Node\n");
  371.             say_error(lastpos,fp);
  372.             return;
  373.         }
  374.         node=(word)atol(p);
  375.         p=strtok(0,"; \n");
  376.         if(!p) type=alltype;
  377.         else type=toupper(*p);
  378.     }
  379.     if(type!='H' && type!='C' && type!='F' && type!='D' && type!='N' && type!='O') {
  380.         fprintf(stderr,"\nInvalid mail type `%c'\n",type);
  381.         say_error(lastpos,fp);
  382.         return;
  383.     }
  384.  
  385.     /* Make mask for outbound flo, packet and arc files */
  386.  
  387.     if(zone!=myzone)sprintf(outbound,"%s.%03x",root,zone);
  388.     else strcpy(outbound,root);
  389.  
  390.     if(net)sprintf(pkt,"%s\\%04x%04x.?UT",outbound,net,node);
  391.     else sprintf(pkt,"%s\\*.?UT",outbound);
  392.  
  393.     /* Removed the following since Bink 2.40 no longer forces call for REQ */
  394.     /* Left the code in in case you need it */
  395.  
  396. /*    if(type!='H')sprintf(req,"%s\\%04x%04x.HEQ",outbound,net,node);
  397.     else sprintf(req,"%s\\%04x%04x.REQ",outbound,net,node);    */
  398.  
  399.     if(net)sprintf(flo,"%s\\%04x%04x.?LO",outbound,net,node);
  400.     else sprintf(flo,"%s\\*.?LO",outbound);
  401.  
  402.     if(!findfirst(pkt,&f,0)) {
  403.         if(type=='F') type='N';
  404.         sprintf(s,"%s\\%s",outbound,f.ff_name);
  405.         s[strlen(s)-3]=type;
  406.         if(net)printf("Changing flavor of %u:%u:%01u's mail to %c\n",zone,net,node,type);
  407.         else printf("Changing flavor of Zone #%u's mail to %c\n",zone,type);
  408.         do {
  409.             if(infile==NULL) {
  410.                 if(!findfirst(s,&f1,0)) {
  411.                     if(f1.ff_fsize==0L) unlink(s);
  412.                     else {
  413.                         infile=fopen(s,"r+b");
  414.                         if(!infile) {
  415.                             fprintf(stderr,"\nCan't open \'%s\'\n",s);
  416.                             break;
  417.                         }
  418.                         fseek(infile,f.ff_fsize-4L,SEEK_SET);
  419.                         while((char)fgetc(infile)!='\0' && !feof(infile));    /* Should be right after first of last NULLs */
  420.                     }
  421.                 }
  422.             }
  423.             if(f.ff_name[9]!=type) {
  424.                 sprintf(s1,"%s\\%s",outbound,f.ff_name);
  425.                 if(!infile)rename(s1,s);
  426.                 else {
  427.                     outfile=fopen(s1,"rb");
  428.                     if(!outfile) {
  429.                         fprintf(stderr,"\nCan't open \'%s\'\n",s1);
  430.                         fclose(infile);
  431.                         infile=NULL;
  432.                         break;
  433.                     }
  434.                     fseek(outfile,(long)sizeof(struct _pkthdr),SEEK_SET);    /* skip header to 1st msg */
  435.                     while (!feof(outfile)) {
  436.                         bytes=fread(s1,1,133,outfile);
  437.                         fwrite(s1,1,bytes,infile);
  438.                         if(bytes!=133) break;
  439.                     }
  440.                     fclose(outfile);
  441.                 }
  442.             }
  443.         } while(!findnext(&f));
  444.     }
  445.     if(infile)fclose(infile);
  446.  
  447.     if(!findfirst(flo,&f,0)) {
  448.         if(type=='N' || type=='O') type='F';
  449.         sprintf(s,"%s\\%s",outbound,f.ff_name);
  450.         s[strlen(s)-3]=type;
  451.         if(net)printf("Changing flavor of %u:%u:%01u's attach(es) to %c\n",zone,net,node,type);
  452.         else printf("Changing flavor of Zone #%u's attach(es) to %c\n",zone,type);
  453.         do {
  454.             if(infile==NULL) {
  455.                 if(!findfirst(s,&f1,0)) {
  456. /*                    if(f1.ff_fsize==0L) unlink(s);
  457.                     else {
  458. */                        infile=fopen(s,"r+b");
  459.                         if(!infile) {
  460.                             fprintf(stderr,"\nCan't open \'%s\'\n",s);
  461.                             break;
  462.                         }
  463.                         fseek(infile,0L,SEEK_END);
  464. /*                    } */
  465.                 }
  466.             }
  467.             if(f.ff_name[9]!=type) {
  468.                 sprintf(s1,"%s\\%s",outbound,f.ff_name);
  469.                 if(!infile)rename(s1,s);
  470.                 else {
  471.                     outfile=fopen(s1,"rb");
  472.                     if(!outfile) {
  473.                         fprintf(stderr,"\nCan't open \'%s\'\n",s1);
  474.                         fclose(infile);
  475.                         infile=NULL;
  476.                         break;
  477.                     }
  478.                     fseek(outfile,0L,SEEK_SET);
  479.                     while (!feof(outfile)) {
  480.                         bytes=fread(s1,1,133,outfile);
  481.                         fwrite(s1,1,bytes,infile);
  482.                         if(bytes!=133) break;
  483.                     }
  484.                     fclose(outfile);
  485.                 }
  486.             }
  487.         } while(!findnext(&f));
  488.     }
  489.     if(infile)fclose(infile);
  490.  
  491. /*    if(!findfirst(req,&f,0)) {
  492.         sprintf(s,"%s\\%s",outbound,f.ff_name);
  493.         if(type=='H')s[strlen(s)-3]='H';
  494.         else {
  495.             type='R';
  496.             s[strlen(s)-3]='R';
  497.         }
  498.         if(net)printf("Changing flavor of %u:%u:%01u's REQ(s) to %c\n",zone,net,node,type);
  499.         else printf("Changing flavor of Zone #%u's REQ(s) to %c\n",zone,type);
  500.         do {
  501.             if(infile==NULL) {
  502.                 if(!findfirst(s,&f1,0)) {
  503.                     if(f1.ff_fsize==0L) unlink(s);
  504.                     else {
  505.                         infile=fopen(s,"r+b");
  506.                         if(!infile) {
  507.                             fprintf(stderr,"\nCan't open \'%s\'\n",s);
  508.                             break;
  509.                         }
  510.                         fseek(infile,0L,SEEK_END);
  511.                     }
  512.                 }
  513.             }
  514.             if(f.ff_name[9]!=type) {
  515.                 sprintf(s1,"%s\\%s",outbound,f.ff_name);
  516.                 if(!infile)rename(s1,s);
  517.                 else {
  518.                     outfile=fopen(s1,"rb");
  519.                     if(!outfile) {
  520.                         fprintf(stderr,"\nCan't open \'%s\'\n",s1);
  521.                         fclose(infile);
  522.                         infile=NULL;
  523.                         break;
  524.                     }
  525.                     fseek(outfile,0L,SEEK_SET);
  526.                     while (!feof(outfile)) {
  527.                         bytes=fread(s1,1,133,outfile);
  528.                         fwrite(s1,1,bytes,infile);
  529.                         if(bytes!=133) break;
  530.                     }
  531.                     fclose(outfile);
  532.                 }
  533.             }
  534.         } while(!findnext(&f));
  535.     }
  536.     if(infile)fclose(infile);
  537. */
  538. }
  539.  
  540.  
  541. void pascal make_poll (char *line,long lastpos,FILE *pf) {
  542.  
  543.     char *p;
  544. /*    char *pw;    */
  545.     word zone,net,node;
  546. /*    word point;    */
  547. /*    FILE *fp;    */
  548.     char s[133];
  549. /*    struct _pkthdr ph;    */
  550.     struct ffblk f;
  551. /*    struct date dd;    */
  552. /*    struct time tt;    */
  553.  
  554.     /* Once created an empty poll packet.  Left the code in (commented
  555.        out) in case you need them.  What I do now is just create an empty
  556.        *.CLO file, which won't be routed on subsequent passes. */
  557.  
  558.     lstrip(line);
  559.     stripcr(line);
  560.     rstrip(line);
  561.     p=strtok(line,":");
  562.     if(!p) return;
  563.     zone=(word)atol(p);
  564.     if(!zone) return;
  565.     p=strtok(0,"/");
  566.     if(!p) return;
  567.     net=(word)atol(p);
  568.     if(!net) return;
  569.     p=strtok(0,". ");
  570.     if(!p) return;
  571.     node=(word)atol(p);
  572. /*    if(strchr(p,'.')) {
  573.         p=strchr(p,'.');
  574.         p++;
  575.         point=(word)atol(p);
  576.     }
  577.     else point=0;
  578. */
  579.  
  580.     /* The empty *.CLO creator */
  581.  
  582.     if(zone!=myzone) sprintf(outbound,"%s\\.%03x",root,zone);
  583.     else strcpy(outbound,root);
  584.     sprintf(s,"%s\\%04x%04x.CLO",outbound,net,node);
  585.     if(findfirst(s,&f,0)) return;
  586.     fclose(fopen(s,"wb"));
  587.     printf("Created poll attach for %u:%u/%01u\n",zone,net,node);
  588.     return;
  589.  
  590. /*  Code below is the empty packet creator, commented out... */
  591. /*
  592.     pw=strtok(0,"\n ");    */        /* Password if any */
  593. /*
  594.     if(zone!=myzone) sprintf(outbound,"%s\\.%03x",root,zone);
  595.     else strcpy(outbound,root);
  596.  
  597.     sprintf(s,"%s\\%04x%04x.CUT",outbound,net,node);
  598.     if(!findfirst(s,&f,0)) return;
  599.  
  600.     fp=fopen(s,"wb");
  601.     if(!fp) {
  602.         fprintf(stderr,"\nCan't open poll packet `%s'\n",s);
  603.         return;
  604.     }
  605.  
  606.     getdate(&dd);
  607.     gettime(&tt);
  608.  
  609.     ph.orig_node=mynode;
  610.     ph.dest_node=node;
  611.     ph.year=dd.da_year;
  612.     ph.month=dd.da_mon;
  613.     ph.day=dd.da_day;
  614.     ph.hour=tt.ti_hour;
  615.     ph.minute=tt.ti_min;
  616.     ph.second=tt.ti_sec;
  617.     ph.rate=0;
  618.     ph.ver=2;
  619.     ph.orig_net=mynet;
  620.     ph.dest_net=net;    */
  621. /*    ph.product=0;    */    /* Until I get a product code (snore) */
  622. /*    ph.rev_lev=201;    */    /* Well, it's gotta be something... */
  623. /*    strset(ph.password,0);
  624.     if(pw) strcpy(ph.password,pw);
  625.     ph.qm_orig_zone=myzone;
  626.     ph.qm_dest_zone=zone;
  627.     strset(ph.TRASH,0);
  628.     ph.orig_zone=myzone;
  629.     ph.dest_zone=zone;
  630.     ph.orig_point=mypoint;
  631.     ph.dest_point=point;
  632.     ph.pr_data=0L;
  633.  
  634.     fwrite(&ph,sizeof(struct _pkthdr),1,fp);
  635.     printf("Created poll packet for %u:%u/%01u.%01u\n",zone,net,node,point);
  636.     fclose(fp);
  637. */
  638. }
  639.  
  640.  
  641.  
  642. char * pascal stristr (char *t, char *s) {
  643.  
  644.    char *t1;
  645.    char *s1;
  646.  
  647.    /* Case-insensitive strstr()--Turbo C didn't have one */
  648.  
  649.    while(*t) {
  650.       t1=t;
  651.       s1=s;
  652.       while(*s1) {
  653.          if (toupper(*s1)!=toupper(*t)) break;
  654.          else {
  655.             s1++;
  656.             t++;
  657.          }
  658.       }
  659.       if (!*s1) return t1;
  660.       t=t1+1;
  661.    }
  662.    return NULL;
  663. }
  664.  
  665.  
  666.  
  667. char pascal spawnit (char *a) {
  668.  
  669.    char *e[27],*p;
  670.    word x;
  671.    union REGS rg;
  672.  
  673.    /* Handle spawning external programs (usually archivers)
  674.       Returns a valid exit code unless you call COMMAND.COM /c <batfile> */
  675.  
  676.    *e=a;
  677.    p=a;
  678.    p=skip_nonwhite(p);
  679.    if(*p) {
  680.        *p=0;
  681.        p++;
  682.        p=skip_white(p);
  683.    }
  684.  
  685.    for (x=1;x<25;x++) {
  686.        if(!*p) {
  687.             e[x]=NULL;
  688.             break;
  689.        }
  690.        e[x]=p;
  691.        p=skip_nonwhite(p);
  692.        if(*p) {
  693.             *p=0;
  694.             p++;
  695.        }
  696.        p=skip_white(p);
  697.    }
  698.  
  699.    rg.x.ax=spawnvp(P_WAIT,a,e);
  700.    if (!rg.x.ax) {
  701.        rg.h.ah=77;
  702.        int86(0x21,&rg,&rg);
  703.    }
  704.    if (debug || more) printf("Exit status: %hu\n",rg.h.al);
  705.    return rg.h.al;
  706. }
  707.  
  708.  
  709.  
  710. long pascal make_msgid (void) {
  711.  
  712.     time_t t;
  713.     static word counter=0;
  714.  
  715.     /* Create a msgid serial number, including a counter */
  716.  
  717.     (void)time(&t);
  718.     t = (t<<4L) | (long)(counter++ & 15);
  719.     return t;
  720. }
  721.  
  722.  
  723.  
  724. char * pascal find_sched (FILE *pf, char *schedtag, int wholefile) {
  725.  
  726.     char *p;
  727.     char s[256];
  728.  
  729.     /* Given a file pointer and schedule tag string, searches file for
  730.        schedule tag and returns it if found.  Returns NULL if not. */
  731.  
  732.     while(1) {
  733.         if(!fgets(s,256,pf)) {
  734.             if(wholefile) {        /* Reset and try once more */
  735.                 wholefile=0;
  736.                 lines=0;
  737.                 fseek(pf,0L,SEEK_SET);
  738.                 continue;
  739.             }
  740.             fprintf(stderr,"\nRequested schedule tag '%s' not found.\n",schedtag);
  741.             return NULL;
  742.         }
  743.         lines++;
  744.         if(debug)printf("%u. %s",lines,s);
  745.         lstrip(s);
  746.         while(p=strchr(s,'\t')) *p=' ';
  747.         if(p=strchr(s,';')) *p=0;
  748.         p=s;
  749.         if(usingbink) {
  750.            if(strnicmp(p,"APPLICATION MAKEARC ",20)) continue; /* Not ours */
  751.            p+=20;
  752.            lstrip(p);
  753.         }
  754.         if(!strnicmp(p,"SCHED ",6)) {
  755.             p+=6;
  756.             lstrip(p);
  757.             stripcr(p);
  758.             rstrip(p);
  759.  
  760.             if(!stricmp(p,schedtag)) {
  761.                 printf("Processing schedule tag '%s'\n",schedtag);
  762.                 break;
  763.             }
  764.         }
  765.     }
  766.     return p;
  767. }
  768.  
  769.  
  770.  
  771. char * pascal skip_white (char *p) {
  772.  
  773.     while(*p && (*p==' ' || *p=='\t')) *p++;
  774.     return p;
  775. }
  776.  
  777.  
  778. char * pascal skip_nonwhite (char *p) {
  779.  
  780.     while(*p && *p!=' ' && *p!='\t')*p++;
  781.     return p;
  782. }
  783.  
  784.  
  785. char * pascal to_delim (char *p, char *delim) {
  786.  
  787.     char *d;
  788.  
  789.     while(*p) {
  790.          d=delim;
  791.          while(*d && *p!=*d) d++;
  792.          if(*p==*d) break;
  793.          p++;
  794.     }
  795.     return p;
  796. }
  797.  
  798.  
  799.  
  800. char * pascal rstrip (char *a) {    /* Remove trailing spaces and tabs */
  801.  
  802.   register int x;
  803.  
  804.   x=strlen(a);
  805.   while (x && a && (a[x-1]==' ' || a[x-1]=='\t')) a[--x]=0;
  806.   return a;
  807. }
  808.  
  809.  
  810.  
  811.  
  812. char * pascal lstrip (char *a) {    /* Remove leading spaces and tabs */
  813.  
  814.   register int x;
  815.  
  816.   x=strlen(a);
  817.   while (x && (*a==' ' || *a=='\t')) memmove (a,(a+1),x--);
  818.   return (a);
  819. }
  820.  
  821.  
  822.  
  823. char * pascal stripcr (char *a) {    /* Remove trailing crs and lfs */
  824.  
  825.   register int x;
  826.  
  827.   x=strlen(a);
  828.   while (x && (a[x-1]=='\n' || a[x-1]=='\r')) a[--x]=0;
  829.   return a;
  830. }
  831.  
  832.  
  833.  
  834.  
  835. int cdecl hardware_error (int errnum,int ax,int bp,int si) {
  836.  
  837.     union REGS rg;
  838.     struct SREGS sg;
  839.     char ch[]="\r\nA very fatal hardware error occured...shutting down now.\r\n$";
  840.     static int counter=0;
  841.  
  842.     if(counter<12 && !didbreak) {
  843.         counter++;
  844.         hardresume(1);    /* Retry 12 times */
  845.     }
  846.  
  847.     /* State that error happened, we're closing up shop */
  848.  
  849.     rg.x.ax=9;
  850.     rg.x.dx=FP_OFF(ch);
  851.     sg.ds=FP_SEG(ch);
  852.     int86x(0x21,&rg,&rg,&sg);
  853.  
  854.     /* Report some info on error */
  855.  
  856.     rg.x.ax=9;
  857.     if(ax>-1) sprintf(ch,"\r\nError was on drive %c:\r\n$",'A'+(char)(ax & 0xFF));
  858.     else sprintf(ch,"\r\nError was in driver at %d:%d\r\n$",bp,si);
  859.     rg.x.dx=FP_OFF(ch);
  860.     sg.ds=FP_SEG(ch);
  861.     int86x(0x21,&rg,&rg,&sg);
  862.  
  863.     hardresume(2);        /* Abort */
  864. }
  865.  
  866.  
  867.  
  868. /*
  869.  
  870.    Note that I left some commented out stuff in this that didn't work, but
  871.    you might find it a useful base from which to add more functions.  At
  872.    least I did go through and put in some comments this time.
  873.  
  874.    As always, you're on your own; goodnight.
  875.  
  876. */
  877.